#include "WiFiConfig.h"

// CSS样式和JavaScript代码
const char *pageStyle = R"(
<style>
:root {
  --primary-color: #4361ee;
  --secondary-color: #3f37c9;
  --accent-color: #4895ef;
  --neutral-color: #f8f9fa;
  --text-color: #212529;
}

body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  margin: 0;
  padding: 0;
  background-color: var(--neutral-color);
  color: var(--text-color);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

header {
  background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
  color: white;
  padding: 20px;
  text-align: center;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

main {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

.card {
  background-color: white;
  border-radius: 10px;
  box-shadow: 0 10px 25px rgba(0,0,0,0.1);
  width: 100%;
  max-width: 400px;
  padding: 20px;
  margin: 20px;
  transition: transform 0.3s ease;
}

.card:hover {
  transform: translateY(-5px);
}

h1 {
  margin: 0;
  font-size: 1.8rem;
  font-weight: 600;
}

h2 {
  color: var(--primary-color);
  font-size: 1.5rem;
  margin-top: 0;
}

.form-group {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
}

select, input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
  box-sizing: border-box;
  font-size: 1rem;
  transition: border-color 0.3s ease;
}

select:focus, input:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px rgba(67, 97, 238, 0.2);
}

.btn {
  background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
  color: white;
  border: none;
  padding: 12px 20px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 500;
  width: 100%;
  transition: all 0.3s ease;
  box-shadow: 0 4px 6px rgba(67, 97, 238, 0.2);
}

.btn:hover {
  background: linear-gradient(135deg, var(--secondary-color), var(--primary-color));
  box-shadow: 0 6px 12px rgba(67, 97, 238, 0.3);
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(1px);
}

.status {
  padding: 15px;
  border-radius: 5px;
  margin-bottom: 15px;
  text-align: center;
}

.success {
  background-color: #e8f5e9;
  color: #2e7d32;
}

.error {
  background-color: #ffebee;
  color: #c62828;
}

.loader {
  border: 3px solid #f3f3f3;
  border-radius: 50%;
  border-top: 3px solid var(--primary-color);
  width: 20px;
  height: 20px;
  animation: spin 1s linear infinite;
  margin: 10px auto;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

footer {
  background-color: #f1f1f1;
  text-align: center;
  padding: 10px;
  font-size: 0.85rem;
  color: #666;
}

@media (max-width: 480px) {
  .card {
    margin: 10px;
    padding: 15px;
  }
  
  h1 {
    font-size: 1.5rem;
  }
  
  h2 {
    font-size: 1.2rem;
  }
}
</style>
)";

// 构造函数
WiFiConfig::WiFiConfig(const char* apName, const char* apPassword) {
    this->apName = apName;
    this->apPassword = apPassword;
    this->server = new WebServer(80);
    this->dnsServer = new DNSServer();
    this->configMode = true;
    this->connecting = false;
    this->connectionStartTime = 0;
}

// 析构函数
WiFiConfig::~WiFiConfig() {
    delete server;
    delete dnsServer;
}

// 扫描WiFi网络
String WiFiConfig::scanNetworks() {
    String networks = "";
    int n = WiFi.scanNetworks();
    if (n == 0) {
        networks = "<option value='' disabled selected>未发现网络</option>";
    } else {
        networks = "<option value='' disabled selected>选择WiFi网络</option>";
        for (int i = 0; i < n; ++i) {
            // 根据信号强度设置选项样式
            String strengthClass = "signal-strong";
            if (WiFi.RSSI(i) < -70)
                strengthClass = "signal-weak";
            else if (WiFi.RSSI(i) < -55)
                strengthClass = "signal-medium";

            networks += "<option value='" + WiFi.SSID(i) + "' class='" + strengthClass + "'>" + WiFi.SSID(i) + " (" + WiFi.RSSI(i) + "dBm)</option>";
        }
    }
    return networks;
}

// 生成头部HTML
String WiFiConfig::getPageHeader(String title) {
    return String("<!DOCTYPE html><html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'>") + "<title>" + title + "</title>" + pageStyle + "</head><body>";
}

// 生成底部HTML
String WiFiConfig::getPageFooter() {
    return "</body></html>";
}

// 处理根路径请求
void WiFiConfig::handleRoot() {
    String page = getPageHeader("ESP32 WiFi配置");
    page += "<header><h1>ESP32智能配网</h1></header>";
    page += "<main><div class='card'>";
    page += "<h2>WiFi配置</h2>";
    page += "<form method='post' action='/connect'>";
    page += "<div class='form-group'>";
    page += "<label for='ssid'>选择WiFi网络:</label>";
    page += "<select id='ssid' name='ssid' required>";
    page += ssidList;
    page += "</select>";
    page += "</div>";
    page += "<div class='form-group'>";
    page += "<label for='password'>输入密码:</label>";
    page += "<input type='password' id='password' name='password' placeholder='WiFi密码'>";
    page += "</div>";
    page += "<button type='submit' class='btn'>连接WiFi</button>";
    page += "</form>";
    page += "</div></main>";
    page += "<footer>ESP32智能配网系统 &copy; 2025</footer>";
    page += getPageFooter();

    server->send(200, "text/html", page);
}

// 处理连接请求
void WiFiConfig::handleConnect() {
    if (server->hasArg("ssid") && server->hasArg("password")) {
        selectedSSID = server->arg("ssid");
        password = server->arg("password");

        String page = getPageHeader("正在连接");
        page += "<header><h1>ESP32智能配网</h1></header>";
        page += "<main><div class='card'>";
        page += "<h2>正在连接</h2>";
        page += "<div class='status'>";
        page += "<p>正在连接到 <strong>" + selectedSSID + "</strong></p>";
        page += "<div class='loader'></div>";
        page += "<p id='connecting-message'>请稍候，正在尝试连接...</p>";
        page += "</div>";
        page += "</div></main>";
        page += "<footer>ESP32智能配网系统 &copy; 2025</footer>";
        page += "<script>";
        page += "setTimeout(function() { window.location.href = '/status'; }, 3000);";
        page += "</script>";
        page += getPageFooter();

        server->send(200, "text/html", page);

        connecting = true;
        connectionStartTime = millis();
        WiFi.begin(selectedSSID.c_str(), password.c_str());
    } else {
        String page = getPageHeader("参数错误");
        page += "<header><h1>ESP32智能配网</h1></header>";
        page += "<main><div class='card'>";
        page += "<div class='status error'>";
        page += "<h2>参数错误</h2>";
        page += "<p>请提供WiFi名称和密码</p>";
        page += "<a href='/' class='btn'>返回</a>";
        page += "</div>";
        page += "</div></main>";
        page += "<footer>ESP32智能配网系统 &copy; 2025</footer>";
        page += getPageFooter();

        server->send(400, "text/html", page);
    }
}

// 处理状态请求
void WiFiConfig::handleStatus() {
    String page = getPageHeader("连接状态");
    page += "<header><h1>ESP32智能配网</h1></header>";
    page += "<main><div class='card'>";

    if (WiFi.status() == WL_CONNECTED) {
        page += "<div class='status success'>";
        page += "<h2>连接成功!</h2>";
        page += "<p>已成功连接到 <strong>" + selectedSSID + "</strong></p>";
        page += "<p>IP地址: <code>" + WiFi.localIP().toString() + "</code></p>";
        page += "<p>您现在可以关闭此页面。</p>";
        page += "</div>";

        // 自动跳转逻辑
        page += "<script>";
        page += "setTimeout(function() {";
        page += "  if (window.opener) {";
        page += "    window.opener.location.reload();";
        page += "    window.close();";
        page += "  } else {";
        page += "    window.location.href = 'http://" + WiFi.localIP().toString() + "';";
        page += "  }";
        page += "}, 5000);";
        page += "</script>";

        configMode = false;
    } else {
        page += "<div class='status error'>";
        page += "<h2>连接失败</h2>";
        page += "<p>无法连接到 <strong>" + selectedSSID + "</strong></p>";
        page += "<p>请检查WiFi名称和密码是否正确</p>";
        page += "<a href='/' class='btn'>返回</a>";
        page += "</div>";

        connecting = false;
    }

    page += "</div></main>";
    page += "<footer>ESP32智能配网系统 &copy; 2025</footer>";
    page += getPageFooter();

    server->send(200, "text/html", page);
}

// 处理自动跳转页面
void WiFiConfig::handleAutoConnect() {
    String page = getPageHeader("正在连接");
    page += "<header><h1>ESP32智能配网</h1></header>";
    page += "<main><div class='card'>";
    page += "<h2>正在连接</h2>";
    page += "<div class='status'>";
    page += "<p>正在尝试连接到已知WiFi网络...</p>";
    page += "<div class='loader'></div>";
    page += "<p id='connecting-message'>如果长时间没有响应，请<a href='/'>点击这里</a>手动配置</p>";
    page += "</div>";
    page += "</div></main>";
    page += "<footer>ESP32智能配网系统 &copy; 2025</footer>";
    page += "<script>";
    page += "setTimeout(function() { window.location.href = '/status'; }, 5000);";
    page += "</script>";
    page += getPageFooter();

    server->send(200, "text/html", page);
}

// 处理所有未注册的URL，重定向到配置页面
void WiFiConfig::handleNotFound() {
    String message = "Redirect to captive portal";
    server->sendHeader("Location", String("http://") + WiFi.softAPIP().toString(), true);
    server->send(302, "text/plain", message);
}

// 初始化配网
void WiFiConfig::begin() {
    Serial.begin(115200);

    // 配置AP模式的IP地址
    IPAddress apIP(192, 168, 4, 1);
    IPAddress netMask(255, 255, 255, 0);

    // 启动AP模式
    WiFi.mode(WIFI_AP_STA);
    WiFi.softAPConfig(apIP, apIP, netMask);
    WiFi.softAP(apName, apPassword);

    Serial.println("AP模式已启动");
    Serial.print("AP IP地址: ");
    Serial.println(WiFi.softAPIP());

    // 配置DNS服务器（兼容旧版库）
    dnsServer->start(DNS_PORT, "*", apIP);

    // 扫描WiFi网络
    ssidList = scanNetworks();

    // 设置服务器路由
    server->on("/", [this]() { this->handleRoot(); });
    server->on("/connect", [this]() { this->handleConnect(); });
    server->on("/status", [this]() { this->handleStatus(); });
    server->on("/auto", [this]() { this->handleAutoConnect(); });
    server->onNotFound([this]() { this->handleNotFound(); }); // 捕获所有未注册的URL

    // 启动服务器
    server->begin();

    // 启动mDNS，以便通过http://esp32.local访问
    if (MDNS.begin("esp32")) {
        Serial.println("mDNS已启动");
    }

    // 尝试连接到最后使用的网络
    WiFi.begin();
    handleAutoConnect();
}

// 处理配网循环（需要在loop()中调用）
void WiFiConfig::handleClient() {
    if (configMode) {
        // 处理DNS请求
        dnsServer->processNextRequest();

        // 处理HTTP请求
        server->handleClient();

        // 如果正在连接，检查连接状态
        if (connecting) {
            if (WiFi.status() == WL_CONNECTED) {
                Serial.println("WiFi连接成功");
                Serial.print("IP地址: ");
                Serial.println(WiFi.localIP());
                connecting = false;
            } else if (millis() - connectionStartTime > CONNECTION_TIMEOUT) {
                Serial.println("WiFi连接超时");
                WiFi.disconnect();
                connecting = false;
            }
        }
    }
}

// 检查是否已连接WiFi
bool WiFiConfig::isConnected() {
    return WiFi.status() == WL_CONNECTED;
}

// 获取当前IP地址
String WiFiConfig::getLocalIP() {
    if (WiFi.status() == WL_CONNECTED) {
        return WiFi.localIP().toString();
    }
    return "";
}

// 获取连接的SSID
String WiFiConfig::getConnectedSSID() {
    if (WiFi.status() == WL_CONNECTED) {
        return WiFi.SSID();
    }
    return "";
}

// 重置配网（清除保存的WiFi信息）
void WiFiConfig::reset() {
    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
    delay(1000);
    WiFi.mode(WIFI_AP_STA);
    configMode = true;
    connecting = false;
}

// 手动启动配网模式
void WiFiConfig::startConfigMode() {
    configMode = true;
    WiFi.mode(WIFI_AP_STA);
    WiFi.softAP(apName, apPassword);
}

// 停止配网模式
void WiFiConfig::stopConfigMode() {
    configMode = false;
    WiFi.softAPdisconnect(true);
}
